﻿/*
Copyright 2011 Shane Ng

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using freemarker.template;
using System.Resources;


namespace Freemarker.Net {
    public class NetObjectWrapper : ObjectWrapper {

        HashSet<Type> extensionsTypes = new HashSet<Type>();

        public HashSet<Type> ExtensionTypes {
            get {
                return extensionsTypes;
            }
        }

        public virtual void AddExtensionNamespace(string ns) {
            var types = this.ExtensionTypes;
            foreach (var a in AppDomain.CurrentDomain.GetAssemblies()) {
                try {
                    foreach (var t in a.GetExportedTypes()) {
                        if (!types.Contains(t) && t.IsClass && t.Name.EndsWith("Extensions") && t.Namespace == ns && t.GetConstructors().Length == 0) {
                            types.Add(t);
                        }
                    }
                }
                catch { }
            }
        }

        public virtual TemplateModel wrap(object obj) {
            if (obj == null){
                return TemplateModel.__Fields.NOTHING;
            } if (obj is TemplateModel) {
                return (TemplateModel)obj;
            } if (obj is ResourceManager) {
                return new ResourceManagerModel(obj, this);
            }
            else if (obj is IDictionary) {
                return new DictionaryModel(obj, this);
            }
            else if (obj is IDictionary<string, object>) {
                return new StringKeyDictionaryModel(obj, this);
            }
            else if (obj is IEnumerable) {
                return new ListModel(obj, this);
            }
            else if (obj is DateTime) {
                return new DateTimeModel(obj);
            }
            else if (obj is Int16) {
                return new NumberModel(obj);
            }
            else if (obj is Int32) {
                return new NumberModel(obj);
            }
            else if (obj is Int64) {
                return new NumberModel(obj);
            }
            else if (obj is Single) {
                return new NumberModel(obj);
            }
            else if (obj is Double) {
                return new NumberModel(obj);
            }
            else if (obj is bool) {
                return new BooleanModel(obj);
            }
            else if (obj is string || obj is Char) {
                return new StringModel(obj);
            }
            else {
                return new NetObjectModel(obj, this);
            }
        }
    }
}
